/*
 * Copyright (C) 2017-2021
 * All rights reserved, Designed By
 * Copyright authorization contact 18814114118
 */
package com.shop.cereshop.business.service.bond.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shop.cereshop.business.dao.bond.CereShopBondDAO;
import com.shop.cereshop.business.dao.bond.CereShopBondRechargeDAO;
import com.shop.cereshop.business.dao.bond.CereShopBondTransactionDAO;
import com.shop.cereshop.business.page.bond.ShopRechargeVO;
import com.shop.cereshop.business.param.bond.ShopRechargeDTO;
import com.shop.cereshop.business.service.bond.CereShopBondService;
import com.shop.cereshop.business.service.bond.CereShopBondTransactionService;
import com.shop.cereshop.commons.constant.IntegerEnum;
import com.shop.cereshop.commons.constant.WalletConstant;
import com.shop.cereshop.commons.domain.bond.CereShopBond;
import com.shop.cereshop.commons.domain.bond.CereShopBondRecharge;
import com.shop.cereshop.commons.domain.bond.CereShopBondTransaction;
import com.shop.cereshop.commons.utils.TimeUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.UUID;

@Slf4j
@Service
@RequiredArgsConstructor
public class CereShopBondServiceImpl extends ServiceImpl<CereShopBondDAO, CereShopBond> implements CereShopBondService {

  private final CereShopBondTransactionService transactionService;

  @Override
  @Transactional(rollbackFor = Exception.class)
  public boolean isPayBound(Long shopId) {
    //根据店铺id查询用户保证金缴纳状态
    CereShopBond shopBond = lambdaQuery()
            .eq(CereShopBond::getShopId, shopId)
            .one();
    if (shopBond == null || shopBond.getBondAmount() == null) {
      return false;
    }
    if (shopBond.getState().equals(IntegerEnum.YES.getCode())) {
        return true;
    }
    //判断缴纳保证金金额是否大于等于保证金阈值
      if (shopBond.getBondAmount().compareTo(shopBond.getNeedPayAmount()) >= 0) {
          //修改保证金缴纳状态
          lambdaUpdate().eq(CereShopBond::getShopId, shopId)
                  .set(CereShopBond::getState, IntegerEnum.YES.getCode())
                  .update();
          return true;
      }
      return false;
  }

  @Override
  public boolean updateBalance(Long shopId, BigDecimal amount, Integer transactionType, String rechargeNo, String description) {
    //1、获取保证金详情
    CereShopBond shopBond = lambdaQuery()
            .eq(CereShopBond::getShopId, shopId)
            .one();

    //2、计算新的保证金金额
    BigDecimal newBondAmount = shopBond.getBondAmount().add(amount);

    //3、检查余额是否足够
    if (amount.compareTo(BigDecimal.ZERO) < 0 && newBondAmount.compareTo(BigDecimal.ZERO) < 0) {
      log.warn("店铺为:{}余额不足，当前余额：{}，消费金额：{}", shopId, shopBond.getBondAmount(), amount);
      return false;
    }

    //4、更新保证金金额
    boolean update;
    if (newBondAmount.compareTo(shopBond.getNeedPayAmount()) >= 0) {
      update = lambdaUpdate().eq(CereShopBond::getShopId, shopId)
              .set(CereShopBond::getState, IntegerEnum.YES.getCode())
              .set(CereShopBond::getBondAmount, newBondAmount)
              .update();
    } else {
      update = lambdaUpdate()
              .eq(CereShopBond::getShopId, shopId)
              .set(CereShopBond::getBondAmount, newBondAmount)
              .update();
    }

    if (update) {
      //5、添加充值流水
      CereShopBondTransaction shopBondTransaction = new CereShopBondTransaction();
      shopBondTransaction.setShopId(shopId)
                      .setBondId(shopBond.getBondId())
                      .setTransactionType(transactionType)
                      .setAmount(amount)
                      .setBalanceBefore(shopBond.getBondAmount())
                      .setBalanceAfter(newBondAmount)
                      .setDescription(description)
                      .setCreateTime(LocalDateTime.now());
      boolean save = transactionService.save(shopBondTransaction);
      if (!save) {
        log.warn("店铺{}流水更新失败，请稍后再试", shopId);
      }
      log.info("店铺{}余额更新成功，变动金额为：{}，新余额为：{}", shopId, amount, newBondAmount);
      return true;
    }
    return false;
  }
}